//////////////////////////////////////////////////////////////////////////

#ifndef _LOADER_H_
#include "loader.h"
#endif

//////////////////////////////////////////////////////////////////////////

#ifndef _SERVERSTATE_H_
#include "serverstate.h"
#endif

//////////////////////////////////////////////////////////////////////////


Loader::Loader( const Buffer& _buffer )
: m_Buffer(_buffer)
{
}


//////////////////////////////////////////////////////////////////////////


Player Loader::LoadPlayer()
{
    return LoadObject<Player>();
}


//////////////////////////////////////////////////////////////////////////


Bullet Loader::LoadBullet()
{
    return LoadObject<Bullet>();
}


//////////////////////////////////////////////////////////////////////////


Wall Loader::LoadWall()
{
    return LoadObject<Wall>();
}


//////////////////////////////////////////////////////////////////////////


ServerState Loader::LoadServerState()
{
    // Save players
    PlayersList playerslist;
    size_t playersCount = m_Buffer.ReadSize_t();
    for ( size_t i = 0; i < playersCount; i++ )
        playerslist.push_back(LoadPlayer());

    // Save bullets
    BulletsList bulletsList;
    size_t bulletsCount = m_Buffer.ReadSize_t();
    for ( size_t i = 0; i < bulletsCount; i++ )
        bulletsList.push_back(LoadBullet());


    // Save walls
    WallsList wallsList;
    size_t wallsCount = m_Buffer.ReadSize_t();
    for ( size_t i = 0; i < wallsCount; i++ )
        wallsList.push_back(LoadWall());

    return ServerState(playerslist, bulletsList, wallsList);
}


//////////////////////////////////////////////////////////////////////////


ClientInput Loader::LoadClientInput()
{
    ClientInput clientInput;
    // Save actions
    clientInput.SetActions(m_Buffer.ReadUInt());

    // Save mouse position
    PE::Point position;
    position.x = m_Buffer.ReadDouble();
    position.y = m_Buffer.ReadDouble();

    clientInput.SetMousePosition(position);

    return clientInput;
}



//////////////////////////////////////////////////////////////////////////


template<typename ObjT>
ObjT Loader::LoadObject()
{
    int ID = m_Buffer.ReadInt();
    
    ObjT obj(ID);

    PE::Point point;
    point.x = m_Buffer.ReadDouble();
    point.y = m_Buffer.ReadDouble();

    obj.SetPosition(point);

    return obj;
}


//////////////////////////////////////////////////////////////////////////


ClientInputPacket Loader::LoadClientInputPacket()
{
    size_t creationTime = m_Buffer.ReadSize_t();
    ClientInput clientInput = LoadClientInput();

    return ClientInputPacket(creationTime, clientInput);
}


//////////////////////////////////////////////////////////////////////////


ClientInfo Loader::LoadClientInfo()
{
    return ClientInfo("");
}


//////////////////////////////////////////////////////////////////////////


ServerInfo Loader::LoadServerInfo()
{
    return ServerInfo();
}


//////////////////////////////////////////////////////////////////////////


ServerStatePacket Loader::LoadServerStatePacket()
{
    size_t creationTime = m_Buffer.ReadSize_t();
    ServerState serverState = LoadServerState();
    return ServerStatePacket(creationTime, serverState);        
}


//////////////////////////////////////////////////////////////////////////


ServerInfoPacket Loader::LoadServerInfoPacket()
{
    ServerInfo serverInfo = LoadServerInfo();
    return ServerInfoPacket(serverInfo);
}


//////////////////////////////////////////////////////////////////////////


ClientInfoPacket Loader::LoadClientInfoPacket()
{
    ClientInfo clientInfo = LoadClientInfo();
    return ClientInfoPacket(clientInfo);
}


//////////////////////////////////////////////////////////////////////////
